package com.itheima.tanhua.dubbo.mongo.api.impl;

import cn.hutool.core.collection.CollUtil;
import com.itheima.tanhua.api.CommentApi;
import com.itheima.tanhua.enums.CommentType;
import com.itheima.tanhua.mongo.Comment;
import com.itheima.tanhua.mongo.Movement;
import com.itheima.tanhua.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

/**
 * @author Lff
 * @date 2022/3/28
 */

@DubboService
public class CommentApiImpl implements CommentApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Integer save(Comment comment) {
        //查询movement
        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
        //填充动态所属用户的UserId
        comment.setPublishUserId(movement.getUserId());
        //保存评论
        mongoTemplate.save(comment);
        //更新表movement
        Query q = Query.query(Criteria.where("id").is(movement.getId()));
        //设置更新字段
        Update update = new Update();
        if (comment.getCommentType() == CommentType.COMMENT.getType()) {
            update.inc("commentCount");
        } else if (comment.getCommentType() == CommentType.LIKE.getType()) {
            update.inc("likeCount");
        } else {
            update.inc("loveCount");
        }
        //构建配置
        FindAndModifyOptions ops = new FindAndModifyOptions();
        //获取最新的更新数据
        ops.returnNew(true);
        //执行修改
        Movement andModify = mongoTemplate.findAndModify(q, update, ops, Movement.class);
        return andModify.staticCount(comment.getCommentType());
    }

    /**
     * 分页查询评论
     *
     * @param movementId
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public List<Comment> findCommentAll(String movementId, CommentType type, Integer page, Integer pagesize) {
        //构建Criteria
        Criteria criteria = Criteria.where("publishId").is(new ObjectId(movementId))
                .and("commentType").is(type.getType());
        Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("created")))
                .skip((page - 1) * pagesize).limit(pagesize);
        //查询并返回
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        return comments;
    }

    /**
     * 判断用户是否已经点赞
     * 动态-评论是否点赞？
     * 视频-评论是否点赞
     *
     * @param targetId 动态ID|动态的评论ID|视频ID|视频评论ID
     * @param id
     * @param type
     * @return
     */
    @Override
    public boolean hasComment(String targetId, Long id, CommentType type) {
        Criteria criteria = Criteria.where("publishId").is(new ObjectId(targetId))
                .and("userId").is(id).and("commentType").is(type.getType());
        Query query = Query.query(criteria);
        return mongoTemplate.exists(query, Comment.class);
    }

    /**
     * @param movementId
     * @param id
     * @return
     */
    @Override
    @Deprecated
    public boolean hasComment(String movementId, Long id) {
        Criteria criteria = Criteria.where("publishId").is(new ObjectId(movementId))
                .and("userId").is(id);
        Query query = Query.query(criteria);
        return mongoTemplate.exists(query, Comment.class);
    }

    /**
     * 取消点赞
     *
     * @param comment
     * @return
     */
    @Override
    public Integer delete(Comment comment) {
        //删除comment表中的数据
        Query delete = Query.query(Criteria.where("publishId").is(comment.getPublishId())
                .and("userId").is(comment.getUserId())
                .and("commentType").is(comment.getCommentType()));
        mongoTemplate.remove(delete, Comment.class);
        //更新表movement
        Query q = Query.query(Criteria.where("id").is(comment.getPublishId()));
        //设置更新字段
        Update update = new Update();
        if (comment.getCommentType() == CommentType.COMMENT.getType()) {
            update.inc("commentCount", -1);
        } else if (comment.getCommentType() == CommentType.LIKE.getType()) {
            update.inc("likeCount", -1);
        } else {
            update.inc("loveCount", -1);
        }
        //构建配置
        FindAndModifyOptions ops = new FindAndModifyOptions();
        //获取最新的更新数据
        ops.returnNew(true);
        //执行修改
        Movement andModify = mongoTemplate.findAndModify(q, update, ops, Movement.class);
        return andModify.staticCount(comment.getCommentType());
    }

    //修改评论的点赞数
    @Override
    public Integer updateCommentLikeCount(Comment comment) {
        //创建Criteria 构建Query
        Query query = Query.query(Criteria.where("userId").is(comment.getUserId())
                .and("id").is(comment.getId()));
        Update update = new Update();
        update.inc("likeCount");
        FindAndModifyOptions ops = new FindAndModifyOptions();
        ops.returnNew(true);
        Comment c = mongoTemplate.findAndModify(query, update, ops, Comment.class);
        //返回点赞数
        return c.getLikeCount();
    }

    //保存评论点赞的记录
    @Override
    public void saveComment(Comment commentSave) {
        //保存  不需要被点赞人id 因为只要有publishId和点赞人id就能确定哪个用户点了哪个评论
        mongoTemplate.save(commentSave);
    }

    /**
     * 减少评论点赞数量
     *
     * @param comment
     * @return
     */
    @Override
    public Integer updateCommentLikeCountRm(Comment comment) {
        //创建Criteria 构建Query
        Query query = Query.query(Criteria.where("userId").is(comment.getUserId())
                .and("id").is(comment.getId()));
        Update update = new Update();
        update.inc("likeCount", -1);
        FindAndModifyOptions ops = new FindAndModifyOptions();
        ops.returnNew(true);
        Comment c = mongoTemplate.findAndModify(query, update, ops, Comment.class);
        //返回点赞数
        return c.getLikeCount();
    }

    /**
     * 删除评论点赞记录
     *
     * @param commentDel
     */
    @Override
    public void delComment(Comment commentDel) {
        Criteria criteria = Criteria.where("userId").is(commentDel.getUserId())
                .and("publishId").is(commentDel.getPublishId());
        Query query = Query.query(criteria);
        mongoTemplate.remove(query, Comment.class);
    }

    /**
     * 根据CommentType查询Comment
     *
     * @param page
     * @param pagesize
     * @param type
     * @return
     */
    @Override
    public List<Comment> getCommentList(Integer page, Integer pagesize, int type, Long userId) {
        Criteria criteria = Criteria.where("commentType").is(type).and("publishUserId").is(userId);
        Query created = Query.query(criteria).with(Sort.by(Sort.Order.desc("created")))
                .skip((page - 1) * pagesize)
                .limit(pagesize);
        //返回
        List<Comment> comments = mongoTemplate.find(created, Comment.class);
        return comments;
    }

    /**
     * 查询指定动态
     * 指定type的
     * 的comment信息
     *
     * @param publishId
     * @param page
     * @param pagesize
     * @param comment
     * @return
     */
    @Override
    public PageResult findCommentByPage(String publishId, Integer page, Integer pagesize, CommentType comment) {
        Query query = new Query();
        query.addCriteria(Criteria.where("publishId").is(new ObjectId(publishId)));
        query.addCriteria(Criteria.where("commentType").is(comment.getType()));
        //统计数量
        long count = mongoTemplate.count(query, Comment.class);
        if (count <= 0) {
            return new PageResult();
        }
        query.with(Sort.by(Sort.Order.desc("created")))
                .skip((page - 1) * pagesize)
                .limit(pagesize);
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        return new PageResult(page, pagesize, count, comments);
    }
}
